
#ifndef __RINGBUFFER_H_
#define __RINGBUFFER_H_

#ifdef __cplusplus
extern "C"{
#endif

#include <stdint.h>

enum {
	AUIOD_FORMAT_S8,
	AUIOD_FORMAT_S16LE,
	AUIOD_FORMAT_S16BE,
};

typedef struct {

	/* 音频数据格式 S16_LE */
	uint32_t format;

	/* 采样率 */
	uint32_t sample_rate;

	/* 声道 */
	uint32_t channels;

} audio_params_t;

/*
 *	@brief: RingBuffer
 */
typedef struct {

    uint8_t *buffer;
    uint32_t size;
    uint32_t mask;
    volatile uint32_t in;  /* Write to */
    volatile uint32_t out; /* Read from */

    audio_params_t audio;

    /* 每次传输音频的最小单元数，一般是2的幂次
	 * 例：一个 S16LE，双通道的音频
	 * 则每次传输音频字节数 = 2B (16bit) x 2 channels = 4 Bytes */
    uint32_t frame;

} ringbuffer_t;

/*
 *	@brief: This function is initialization for ringbuffer content
 *	@param[_this]:		ringbuffer content
 *	@param[buffer]:		ring data buffer pointer
 *	@param[size]:		ring data buffer size
 *	@return:			0 	- success
 *						-1 	- failed
 */
int32_t ringbuffer_init(ringbuffer_t *this, uint8_t *buffer, uint32_t size, \
                        uint32_t format, uint32_t sample_rate, uint32_t channels);

/*
 *	@brief: This function is de-initialization for ringbuffer content
 *	@param[_this]:		ringbuffer content
 *	@return:			0 	- success
 */
int32_t ringbuffer_deinit(ringbuffer_t *this);

/*
 *	@brief: This function get ring buffer free size
 *	@param[_this]:		ringbuffer content
 *	@return:			free size
 */
uint32_t ringbuffer_free_space(ringbuffer_t *this);

/*
 *	@brief: This function get ring buffer used size
 *	@param[_this]:		ringbuffer content
 *	@return:			used size
 */
uint32_t ringbuffer_used_space(ringbuffer_t *this);


int32_t ringbuffer_write_frames(ringbuffer_t *this, uint8_t *data, uint32_t frames);


void ringbuffer_hexdump(ringbuffer_t *this, const void *data, size_t size, \
                        const char *str, ...);

#if 0
/*
 *	@brief: This function get ring buffer data pointer
 *	@param[_this]:		ringbuffer content
 *	@param[data]:		get the getting data pointer
 *	@param[contiguous_bytes]:	getting data size which can be get
 *	@return:			0	- success
 */
signed char ringbuffer_get_data(ringbuffer_t *this, unsigned char** data, unsigned int* contiguous_bytes);

/*
 *	@brief: This function consume ring buffer size
 *	@param[_this]:		ringbuffer content
 *	@param[bytes_consumed]:		consume the data size
 *	@rteturn:			0	- success
 */
signed char ringbuffer_consume(ringbuffer_t *this, unsigned int bytes_consumed);

/*
 *	@brief: This function write data to ring buffer
 *	@param[_this]:		ringbuffer content
 *	@param[data]:		writing data pointer
 *	@param[data_length]:		write data size
 *	@return:			amount of copy size
 */
signed int ringbuffer_write(ringbuffer_t *this, const unsigned char* data, unsigned int data_length);

/*
 *	@brief:	This function get the full flag
 *	@param[_this]:		ringbuffer content
 *	@return:			0 	- not full
 *						1	- full
 */
unsigned char ringbuffer_is_full(ringbuffer_t *_this);

/*
 *	@brief:	This function reset ringbuffer content
 *	@param[_this]:		ringbuffer content
 *	@return:			0	- success
 *						1	- failed
 */
signed char ringbuffer_reset(ringbuffer_t *_this);

void ringbuffer_dump(ringbuffer_t *_this, unsigned int in, unsigned int out);
void ringbuffer_info(ringbuffer_t *_this);
#endif

#ifdef __cplusplus
}
#endif

#endif /* __RINGBUFFER_H_ */

